﻿using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Globalization;
using System.Linq;
using System.Threading;
using Microsoft.Practices.Composite.Events;
using SS.AspNet.Localization.Event;
using SS.AspNet.Utilities;
using SS.Common.Utilities;

namespace SS.AspNet.Localization
{
    /// <summary>
    /// The class is used to manage translation
    /// </summary>
    [Export(typeof(TranslationManager))]
    [PartCreationPolicy(CreationPolicy.Shared)]
    public class TranslationManager
    {
        #region Properties

        /// <summary>
        /// Provides properties and methods for translation
        /// </summary>
        public ITranslationProvider TranslationProvider { get; set; }

        /// <summary>
        /// Get current language
        /// </summary>
        public CultureInfo CurrentLanguage
        {
            get { return Thread.CurrentThread.CurrentUICulture; }
            set
            {
                if (value != Thread.CurrentThread.CurrentUICulture)
                {
                    Thread.CurrentThread.CurrentUICulture = value;
                    Thread.CurrentThread.CurrentCulture = value;
                    OnLanguageChanged();
                }
            }
        }

        /// <summary>
        /// Get languages list
        /// </summary>
        public IEnumerable<CultureInfo> Languages
        {
            get
            {
                return TranslationProvider != null ? TranslationProvider.Languages : Enumerable.Empty<CultureInfo>();
            }
        }

        #endregion

        #region Public Events

        /// <summary>
        /// Notify that current language has been changed
        /// </summary>
        private void OnLanguageChanged()
        {
            IoC.Get<IEventAggregator>().GetEvent<LanguageChangedEvent>().Publish(null);
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// Execute language translate
        /// </summary>
        /// <param name="key">From key to message has been translate</param>
        /// <returns>Translated message</returns>
        public object Translate(string key)
        {
            object result = null;
            if (key != null)
            {
                result = string.Format("!{0}!", key);
                if (TranslationProvider != null)
                {
                    var translatedValue = TranslationProvider.Translate(key);
                    if (translatedValue != null)
                    {
                        result = translatedValue;
                    }
                }
            }
            return result;
        }

        /// <summary>
        /// Execute language translate
        /// </summary>
        /// <param name="key">From key to message has been translate</param>
        /// <param name="args">The parameter list for translation</param>
        /// <returns>Translated message</returns>
        public object Translate(string key, params object[] args)
        {
            object result = null;
            if (key != null)
            {
                result = string.Format("!{0}!", key);
                if (TranslationProvider != null)
                {
                    var translatedValue = TranslationProvider.Translate(key);
                    if (translatedValue != null)
                    {
                        result = string.Format((string)translatedValue, args);
                    }
                }
            }
            return result;
        }

        /// <summary>
        /// Determines the key has been defined in language list
        /// </summary>
        /// <param name="key">Key to verify</param>
        /// <returns>True: key does not exist - False: otherwise</returns>
        public bool CheckExistKey(string key)
        {
            var result = false;
            if (key != null)
            {
                if (TranslationProvider != null)
                {
                    var translatedValue = TranslationProvider.Translate(key);
                    if (translatedValue != null)
                    {
                        result = true;
                    }
                }
            }
            return result;
        }

        #endregion
    }
}
